package com.chao.common.util;

import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

import static java.time.format.DateTimeFormatter.ISO_DATE;

/**
 * 时间工具类 包括 格式化 时间计算 区间判断
 * chao
 */
public final class DateUtile{

    /**
     * 年月日时分秒 带分隔符
     */
    public static final String YYYY_MM_DD_HHMMSS = "yyyy-MM-dd HH:mm:ss";

    /**
     * 年月日时分秒 不带分隔符
     */
    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    /**
     * 年月日时分 带分隔符
     */
    public static final String YYYY_MM_DD_HHMM = "yyyy-MM-dd HH:mm";

    /**
     * 年月日时分 带分隔符
     */
    public static final String YYYY_MM_DD_HH = "yyyy-MM-dd HH";

    /**
     * 年月日时分 不带分隔符
     */
    public static final String YYYYMMDDHHMM = "yyyyMMddHHmm";

    /**
     * 年月日 带分隔符
     */
    public static final String YYYY_MM_DD = "yyyy-MM-dd";

    /**
     * 年月日 不带分隔符
     */
    public static final String YYYYMMDD = "yyyyMMdd";

    /**
     * 年月 带分隔符
     */
    public static final String YYYY_MM = "yyyy-MM";

    /**
     * 年月 不带分隔符
     */
    public static final String YYYYMM = "yyyyMM";

    /**
     * 月
     */
    public static final String MM = "MM";

    /**
     * 天
     */
    public static final String DD = "dd";

    /**
     * 时分秒
     */
    public static final String HHMMSS = "HH:mm:ss";

    /**
     * 时分
     */
    public static final String HHMM = "HH:mm";

    /**
     * 年月日时分秒 中文版格式化
     */
    public static final String NYYYYMMDDHHMMSS = "yyyy年MM月dd日HH时mm分ss秒";

    /**
     * 年月日 中文版格式化
     */
    public static final String NYYYYMMDD="yyyy年MM月dd日";

    /**
     * 年月 中文版格式化
     */
    public static final String NYYYYMM="yyyy年MM月";

    /**
     * yyyy-MM-ddTHH:mmZ格式化
     */
    public static final String YYYYMMDDHHMMSS8="yyyy-MM-dd'T'HH:mm:ss'+'mm:ss";

    /**
     * yyyy-MM-ddTHH:mmZ格式化
     */
    public static final String YYYYMMDDTHHMMSS="yyyy-MM-dd'T'HH:mm:ss";

    /**
     * EEE MMM dd HH:mm:ss zzz yyyy格式化
     */
    public static final String EMDHHMMSS ="EEE MMM dd HH:mm:ss zzz yyyy";

    /**
     * 月日 带分隔符
     */
    public static final String MM_DD = "MM-dd";

    /**
     * 月日 时分 带分隔符
     */
    public static final String MM_DD_HH_MM = "MM-dd HH:mm";

    /**
     * 月日 时分 带分隔符
     */
    public static final String MM_DD_HH_00 = "MM-dd HH:00";

    /**
     * 计算两日期相差的周数 （日历逻辑）
     *
     * @param startDate 开始时间
     * @return Integer
     */
    public static long calculateWeeksBetween(String startDate) {
        // 将 Date 转换为 LocalDate
        LocalDate startLocalDate = DateUtile.getHmd(startDate).toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate today = LocalDate.now();

        // 统计周日的数量
        long sundayCount = 0;

        // 从开始日期到今天，遍历每一天
        for (LocalDate date = startLocalDate; !date.isAfter(today); date = date.plusDays(1)) {
            if (date.getDayOfWeek().getValue() == 7) { // 7代表周日
                sundayCount++;
            }
        }

        return sundayCount;
    }

    /**
     * 按照指定格式  格式化时间
     */
    public static String dateToString(Date date, String pattern) {
        if (null == date) {
            return null;
        } else {
            return new SimpleDateFormat(pattern).format(date);
        }
    }

    /**
     * 将时间格式化为 MM-dd HH:mm
     */
    public static String toMdhm(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,MM_DD_HH_MM);
        }
    }

    /**
     * 将时间格式化为 MM-dd HH:00
     */
    public static String toMdh0(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,MM_DD_HH_00);
        }
    }

    /*--------------------yyyy-MM-dd HH:mm:ss----------------*/

    /**
     * 将时间格式化为 yyyy-MM-dd HH:mm:ss
     */
    public static String toYmdhms(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,YYYY_MM_DD_HHMMSS);
        }
    }

    /**
     * 将当前时间格式化为 yyyy-MM-dd HH:mm:ss
     */
    public static String toYmdhms() {
        return dateToString(new Date(),YYYY_MM_DD_HHMMSS);
    }

    /**
     * 将时间格式化为 yyyyMMddHHmmss
     */
    public static String toymdhms(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,YYYYMMDDHHMMSS);
        }
    }

    /**
     * 将当前时间格式化为 yyyyMMddHHmmss
     */
    public static String toymdhms() {
        return dateToString(new Date(),YYYYMMDDHHMMSS);
    }

    /**
     * 将时间格式化为 yyyy年MM月dd日HH时mm分ss秒
     */
    public static String toNymdhms(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,NYYYYMMDDHHMMSS);
        }
    }

    /**
     * 将当前时间格式化为 yyyy年MM月dd日HH时mm分ss秒
     */
    public static String toNymdhms() {
        return dateToString(new Date(),NYYYYMMDDHHMMSS);
    }

    /*--------------------yyyy-MM-dd HH:mm----------------*/

    /**
     * 将时间格式化为 yyyy-MM-dd HH:mm
     */
    public static String toYmdhm(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,YYYY_MM_DD_HHMM);
        }
    }

    /**
     * 将时间格式化为 yyyy-MM-dd HH
     */
    public static String toYmdh(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,YYYY_MM_DD_HH);
        }
    }

    /**
     * 将当前时间格式化为 yyyy-MM-dd HH:mm
     */
    public static String toYmdhm() {
        return dateToString(new Date(),YYYY_MM_DD_HHMM);
    }

    /**
     * 将时间格式化为 yyyyMMddHHmm
     */
    public static String toymdhm(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,YYYYMMDDHHMM);
        }
    }

    /**
     * 将当前时间格式化为 yyyyMMddHHmm
     */
    public static String toymdhm() {
        return dateToString(new Date(),YYYYMMDDHHMM);
    }

    /*--------------------yyyy-MM-dd----------------*/

    /**
     * 将时间格式化为 yyyy-MM-dd
     */
    public static String toYmd(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,YYYY_MM_DD);
        }
    }

    /**
     * 将当前时间格式化为 yyyy-MM-dd
     */
    public static String toYmd() {
        return dateToString(new Date(),YYYY_MM_DD);
    }

    /**
     * 将时间格式化为 yyyyMMdd
     */
    public static String toymd(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,YYYYMMDD);
        }
    }

    /**
     * 将当前时间格式化为 yyyyMMdd
     */
    public static String toymd() {
        return dateToString(new Date(),YYYYMMDD);
    }

    /**
     * 将时间格式化为 yyyy年MM月dd日
     */
    public static String toNymd(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,NYYYYMMDD);
        }
    }

    /**
     * 将当前时间格式化为 yyyy年MM月dd日
     */
    public static String toNymd() {
        return dateToString(new Date(),NYYYYMMDD);
    }

    /*--------------------yyyy-MM----------------*/

    /**
     * 将时间格式化为 yyyy-MM
     */
    public static String toYm(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,YYYY_MM);
        }
    }

    /**
     * 将当前时间格式化为 yyyy-MM
     */
    public static String toYm() {
        return dateToString(new Date(),YYYY_MM);
    }

    /**
     * 将时间格式化为 yyyyMM
     */
    public static String toym(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,YYYYMM);
        }
    }

    /**
     * 将当前时间格式化为 yyyyMM
     */
    public static String toym() {
        return dateToString(new Date(),YYYYMM);
    }

    /**
     * 将时间格式化为 yyyy年MM月
     */
    public static String toNym(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,NYYYYMM);
        }
    }

    /**
     * 将当前时间格式化为 yyyy年MM月
     */
    public static String toNym() {
        return dateToString(new Date(),NYYYYMM);
    }

    /*--------------------HH:mm:ss----------------*/

    /**
     * 将时间格式化为 HH:mm:ss
     */
    public static String toHms(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,HHMMSS);
        }
    }

    /**
     * 将当前时间格式化为 HH:mm:ss
     */
    public static String toHms() {
        return dateToString(new Date(),HHMMSS);
    }

    /**
     * 将时间格式化为 HH:mm
     */
    public static String toHm(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,HHMM);
        }
    }

    /**
     * 将时间格式化为 MM-DD
     */
    public static String toMm(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,MM_DD);
        }
    }

    /**
     * 将当前时间格式化为 HH:mm
     */
    public static String toHm() {
        return dateToString(new Date(),HHMM);
    }

    /*------------------------------------------------*/

    /**
     * 按照指定格式  将字符串转时间对象
     */
    public static Date stringToDate(String date, String pattern) {
        if (null == pattern) {
            return null;
        } else {
            return new SimpleDateFormat(pattern).parse(date,new ParsePosition(0));
        }
    }

    /**
     * yyyy-MM-dd HH 格式字符串转时间
     */
    public static Date getHmdh(String date) {
        if (null == date) {
            return null;
        } else {
            return stringToDate(date,YYYY_MM_DD_HH);
        }
    }

    /**
     * yyyy-MM-dd HH:mm:ss 格式字符串转时间
     */
    public static Date getHmdhms(String date) {
        if (null == date) {
            return null;
        } else {
            return stringToDate(date,YYYY_MM_DD_HHMMSS);
        }
    }

    /**
     * yyyyMMddHHmmss 格式字符串转时间
     */
    public static Date gethmdhms(String date) {
        if (null == date) {
            return null;
        } else {
            return stringToDate(date,YYYYMMDDHHMMSS);
        }
    }

    /**
     * yyyy-MM-dd 格式字符串转时间
     */
    public static Date getHmd(String date) {
        if (null == date) {
            return null;
        } else {
            return stringToDate(date,YYYY_MM_DD);
        }
    }

    /**
     * yyyyMMdd 格式字符串转时间
     */
    public static Date gethmd(String date) {
        if (null == date) {
            return null;
        } else {
            return stringToDate(date,YYYYMMDD);
        }
    }

    /**
     * yyyy-MM-dd HH:mm 格式字符串转时间
     */
    public static Date getHmdhm(String date) {
        if (null == date) {
            return null;
        } else {
            return stringToDate(date,YYYY_MM_DD_HHMM);
        }
    }

    /**
     * yyyy-MM-dd 格式字符串转时间
     */
    public static Date getYm(String date) {
        if (null == date) {
            return null;
        } else {
            return stringToDate(date,YYYY_MM);
        }
    }

    /*---------------------------------------------*/

    /**
     * 时间加减(小时)
     */
    public static Date editH(Date date,Integer h) {
        return getDateCalculation(Calendar.HOUR_OF_DAY,date,h);
    }

    /**
     * 时间加减(天)
     */
    public static Date editD(Date date,Integer h) {
        return getDateCalculation(Calendar.DATE,date,h);
    }

    /**
     * 时间加减(月)
     */
    public static Date editM(Date date,Integer h) {
        return getDateCalculation(Calendar.MONTH,date,h);
    }

    /**
     * 时间加减(年)
     */
    public static Date editY(Date date,Integer h) {
        return getDateCalculation(Calendar.YEAR,date,h);
    }

    /**
     * 时间加减(周)
     */
    public static Date editW(Date date,Integer h) {
        Calendar calendar = getCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.WEEK_OF_YEAR, h);
        return calendar.getTime();
    }

    /**
     * 时间加减(自定义)
     */
    public static Date getDateCalculation(Integer s,Date date,Integer h) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(s, h);
        return calendar.getTime();
    }

    /**
     * 判断时间是否在某一时间段内
     */
    public static boolean belongTime(Date nowTime,Date startTime,Date endTime){

        Calendar calendar=Calendar.getInstance();
        calendar.setTime(nowTime);

        Calendar beginsTime=Calendar.getInstance();
        beginsTime.setTime(startTime);

        Calendar endsTime=Calendar.getInstance();
        endsTime.setTime(endTime);

        if(calendar.after(beginsTime)&&calendar.before(endsTime)){
            return true;
        }
        return false;
    }

    /**
     * 计算日期差
     */
    public static long belongTimeLong(Date endTime){
        LocalDate startDate = LocalDate.now();
        LocalDate endDate = date2LocalDate(endTime);
        return Math.abs(ChronoUnit.DAYS.between(startDate, endDate));
    }

    /**
     * 计算日期差
     */
    public static long belongTimeLong(Date startTime,Date endTime){
        LocalDate startDate = date2LocalDate(startTime);
        LocalDate endDate = date2LocalDate(endTime);
        return Math.abs(ChronoUnit.DAYS.between(startDate, endDate));
    }

    /**
     * Date转LocalDate
     * @param date
     */
    public static LocalDate date2LocalDate(Date date) {
        if(null == date) {
            return null;
        }
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    }

    /**
     * 判断当前时间是否在某一时间段内
     */
    public static boolean belongTime(Date startTime,Date endTime){
        return belongTime(new Date(),startTime,endTime);
    }

    /**
     * 将时间转为当天 00:00:00
     */
    public static Date toStart(Date startTime){
        return gethmdhms(toymd(startTime)+"000000");
    }

    /**
     * 将时间转为当天 23:59:59
     */
    public static Date toEnd(Date endTime){
        return gethmdhms(toymd(endTime)+"235959");
    }

    /**
     * 时间戳转 yyyy-MM-dd
     */
    public static String timestampToYmd(String timestamp){
        return toYmd(new Date(Long.parseLong(timestamp)));
    }

    /**
     * 将短时间格式字符串转换为时间 HH:mm
     */
    public static Date strToDateMinute(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat(HHMM);
        ParsePosition pos = new ParsePosition(0);
        return formatter.parse(strDate, pos);
    }


    /**
     * yyyy-MM-ddTHH:mmZ格式化
     */
    public static Date yyyy8ToDate(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat(YYYYMMDDHHMMSS8);
        ParsePosition pos = new ParsePosition(0);
        return formatter.parse(strDate, pos);
    }

    /**
     * yyyy-MM-ddTHH:mmZ格式化
     */
    public static Date yyyyToDate(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat(YYYYMMDDTHHMMSS);
        ParsePosition pos = new ParsePosition(0);
        return formatter.parse(strDate, pos);
    }


    /**
     *  EEE MMM dd HH:mm:ss zzz yyyy格式化
     */
    public static Date emdStrToDate(String strDate) {
        try {
            SimpleDateFormat formatter = new SimpleDateFormat(EMDHHMMSS, Locale.US);
            return formatter.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将时间格式化为 MM-dd
     */
    public static String toMd(Date date) {
        if (null == date) {
            return null;
        } else {
            return dateToString(date,MM_DD);
        }
    }

    /**
     * 将当前时间格式化为 MM-dd
     */
    public static String toMd() {
        return dateToString(new Date(),MM_DD);
    }

    /**
     * 时间格式化
     * 例: 3500秒 转为 58分
     */
    public static String getDate(Integer date) {
        if (date < 1) {
            return "0分钟";
        }
        if (date<60) {
            return date+"秒";
        }else if (date < 3600) {
            int m = date/60;
            return m+"分钟";
        }else if(date < 86400) {
            int h = date/3600;
            int m = (date%3600)/60;
            if(m > 0){
                return h+"小时"+m+"分钟";
            }else{
                return h+"小时";
            }
        }else {
            int day = date/86400;
            int h = (date%86400)/3600;
            if (h > 0){
                return day+"天"+h+"小时";
            }else {
                return day+"天";
            }
        }
    }


    /**
     * 根据数字月获取对应的中文
     */
    public static String getMonth(int months) {
        String month = "";
        switch (months) {
            case 1:
                month = "一月";
                break;
            case 2:
                month = "二月";
                break;
            case 3:
                month = "三月";
                break;
            case 4:
                month = "四月";
                break;
            case 5:
                month = "五月";
                break;
            case 6:
                month = "六月";
                break;
            case 7:
                month = "七月";
                break;
            case 8:
                month = "八月";
                break;
            case 9:
                month = "九月";
                break;
            case 10:
                month = "十月";
                break;
            case 11:
                month = "十一月";
                break;
            case 12:
                month = "十二月";
                break;
            default:
                break;
        }
        return month;
    }

    /**
     * 计算两个日期相差天数
     */
    public static int getDifferDays(Date beforeYmd,Date afterYmd) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(beforeYmd);
        long time1 = cal.getTimeInMillis();
        cal.setTime(afterYmd);
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 计算两个日期相差天数
     */
    public static int getDifferMinutes(Date beforeYmd,Date afterYmd) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(beforeYmd);
        long time1 = cal.getTimeInMillis();
        cal.setTime(afterYmd);
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*60);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 获取当前月一共有多少天
     */
    public static int getDaysOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取时间区间所有时间  MM  1 2 3 4
     */
    public static int[] getBeforeAllMonths(LocalDate date, int num){
        if (num < 1){
            return null;
        }
        int count = num-1;
        int[] months = new int[num];
        for (int i = count; i >=0 ; i--){
            months[count-i] = date.plusMonths(-i).getMonthValue();
        }
        return months;
    }

    /**
     * 获取时间区间所有时间  MM月 1月 2月 3月
     */
    public static String[] getBeforeAllMonthsM(LocalDate date, int num){
        if (num < 1){
            return new String[]{date.getMonthValue() + "月"};
        }
        int count = num-1;
        String[] months = new String[num];
        for (int i = count; i >=0 ; i--){
            months[count-i] = date.plusMonths(-i).getMonthValue() + "月";
        }
        return months;
    }

    /**
     * 获取时间区间所有月 YYYY-MM 2021-01 2021-02
     */
    public static List<String> getBeforeAllMonthsOfYear(LocalDate date, int num){
        List<String> result = new ArrayList<>();
        if (num < 1){
            result.add(date.format(DateTimeFormatter.ofPattern("yyyy-MM")));
            return result;
        }
        int count = num-1;
        for (int i = count; i >=0 ; i--){
            result.add(date.plusMonths(-i).format(DateTimeFormatter.ofPattern("yyyy-MM")));
        }
        return result;
    }

    /**
     * 获取月份的第一天
     */
    public static String getMonthFirstDay(LocalDate date){
        return date.with(TemporalAdjusters.firstDayOfMonth()).toString();
    }

    /**
     * 获取月份的最后一天
     */
    public static String getMonthEndDay(String date){
        return LocalDate.parse(date,ISO_DATE).with(TemporalAdjusters.lastDayOfMonth()).toString();
    }

    /**
     * 计算时间差（秒） t2 > t1
     * @param time1
     * @param time2
     * @param format 格式
     * @return
     */
    public static long getDiffSeconds(String time1, String time2, String format){
        Date t1 = stringToDate(time1, format);
        Date t2 = stringToDate(time2, format);
        return (t2.getTime() - t1.getTime())/1000;
    }
    /**
     * 计算时间差（分） t2 > t1
     * @param time1
     * @param time2
     * @param format 格式
     * @return
     */
    public static long getDiffMinute(String time1, String time2, String format){
        Date t1 = stringToDate(time1, format);
        Date t2 = stringToDate(time2, format);
        return (t2.getTime() - t1.getTime())/(1000*60);
    }

    /**
     * 计算时间差（小时） t2 > t1
     * @param time1 yyyy-mm-dd hh:mm
     * @param time2 yyyy-mm-dd hh:mm
     * @param format 格式
     * @return
     */
    public static long getDiffHours(String time1, String time2, String format){
        Date t1 = stringToDate(time1, format);
        Date t2 = stringToDate(time2, format);
        return (t2.getTime() - t1.getTime())/(1000*60*60);
    }

    /**
     * 日期设置
     * @return
     */
    public static Calendar getCalendar(){
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);//设置每周的第一天为星期一
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); //设置每周从周一开始
        calendar.setMinimalDaysInFirstWeek(7); //设置一周至少7天
        return calendar;
    }

    /**
     *获取所在周的某一天日期
     * @return
     */
    public static String laseWook(){
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        return dateToString(calendar.getTime(), YYYY_MM_DD);
    }

    /**
     *获取所在周的某一天日期
     * @param date 日期
     * @param day 星期几(周一为一周的第一天)
     * @return
     */
    public static String getDayOfWeekDate(Date date, Integer day){
        Calendar calendar = getCalendar();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_WEEK, day);
        return dateToString(calendar.getTime(), YYYY_MM_DD);
    }

    /**
     * 获取所在月的某一天日期
     * @param date 日期
     * @param day 几天(如果大于最后一天，则默认最后一天)
     * @return
     */
    public static String getDayOfMonthDate(Date date, Integer day){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        if (day >= calendar.getActualMaximum(Calendar.DAY_OF_MONTH)){
            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        }else {
            calendar.set(Calendar.DAY_OF_MONTH, day);
        }
        return dateToString(calendar.getTime(), YYYY_MM_DD);
    }

    /**
     * 获取日期所在年周
     * @param date
     * @return
     */
    public static String getWeekOfYear(Date date){
        Calendar calendar = getCalendar();
        calendar.setTime(date);
        return  calendar.getWeekYear() + ":" + calendar.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 获取日期所在年月
     * @param date
     * @return
     */
    public static String getMonthofYear(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH) + 1);
    }

    /**
     * 获取时间的月
     */
    public static String getMM(String date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(getHmd(date));
        return (calendar.get(Calendar.MONTH) + 1) + "月";
    }

    /**
     * 获取时间的天
     */
    public static String getDD(String date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(getHmd(date));
        return calendar.get(Calendar.DAY_OF_MONTH) + "日";
    }

    /**
     * 获取所有周
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<String> getBetweentWeeks(Date startDate, Date endDate){
        List<String> result = new ArrayList<>();
        Calendar c = getCalendar();
        Calendar c2 = getCalendar();
        c.setTime(startDate);
        c2.setTime(endDate);
        String startW = c.getWeekYear() + ":" + c.get(Calendar.WEEK_OF_YEAR);
        String endW = c2.getWeekYear() + ":" + c2.get(Calendar.WEEK_OF_YEAR);
        if (startDate.after(endDate) || startW.equals(endW)){
            return result;
        }
        while (!startW.equals(endW)) {
            result.add(startW);
            c.add(Calendar.WEEK_OF_YEAR, 1);
            startW = c.getWeekYear() + ":" + c.get(Calendar.WEEK_OF_YEAR);
        };
        result.add(endW);
        return result;
    }

    /**
     * 获取所有月
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<String> getBetweentMonths(Date startDate, Date endDate){
        List<String> result = new ArrayList<>();
        Calendar c = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c.setTime(startDate);
        c2.setTime(endDate);
        String startM = c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1);
        String endM = c2.get(Calendar.YEAR) + "-" + (c2.get(Calendar.MONTH) + 1);
        if (startDate.after(endDate) || startM.equals(endM)){
            return result;
        }
        while (!startM.equals(endM)){
            result.add(startM);
            c.add(Calendar.MONTH, 1);
            startM = c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1);
        }
        result.add(endM);
        return result;
    }

    /**
     * 获取所有月-开始时间和结束时间为同一月返回月
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<String> getAllBetweentMonths(Date startDate, Date endDate){
        List<String> result = new ArrayList<>();
        Calendar c = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c.setTime(startDate);
        c2.setTime(endDate);
        String startM = c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1);
        String endM = c2.get(Calendar.YEAR) + "-" + (c2.get(Calendar.MONTH) + 1);
        if (startDate.after(endDate)){
            return result;
        }
        if (startM.equals(endM)){
            result.add(startM);
            return result;
        }
        while (!startM.equals(endM)){
            result.add(startM);
            c.add(Calendar.MONTH, 1);
            startM = c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1);
        }
        result.add(endM);
        return result;
    }

    /**
     * 获取所有时间区间天日期
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<String> getBetweentDates(Date startDate, Date endDate){
        List<String> result = new ArrayList<>();
        if (startDate.getTime() > endDate.getTime()){
            return result;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        while (true){
            if (dateToString(c.getTime(), YYYY_MM_DD).equals(dateToString(endDate, YYYY_MM_DD))){
                result.add(dateToString(c.getTime(), YYYY_MM_DD));
                break;
            }
            result.add(dateToString(c.getTime(), YYYY_MM_DD));
            c.add(Calendar.DATE, 1);
        }
        return result;
    }

    /**
     * M-DD  3-1
     * @param date
     * @return
     */
    public static String toMDD(Date date){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return (c.get(Calendar.MONTH) + 1) + "-" + c.get(Calendar.DAY_OF_MONTH);
    }


    /**
     * 获取所有时间区间天日期
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<String> getBetweentDateMDD(Date startDate, Date endDate){
        List<String> result = new ArrayList<>();
        if (startDate.getTime() > endDate.getTime()){
            return result;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        while (true){
            if (dateToString(c.getTime(), YYYY_MM_DD).equals(dateToString(endDate, YYYY_MM_DD))){
                result.add((c.get(Calendar.MONTH) + 1) + "-" + c.get(Calendar.DAY_OF_MONTH));
                break;
            }
            result.add((c.get(Calendar.MONTH) + 1) + "-" + c.get(Calendar.DAY_OF_MONTH));
            c.add(Calendar.DATE, 1);
        }
        return result;
    }

    /**
     * 获取所有时间区间天日期
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<String> getBetweentDateMMDD(Date startDate, Date endDate){
        List<String> result = new ArrayList<>();
        if (startDate.getTime() > endDate.getTime()){
            return result;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        while (true){
            if (dateToString(c.getTime(), YYYY_MM_DD).equals(dateToString(endDate, YYYY_MM_DD))){
                result.add(dateToString(c.getTime(),MM_DD));
                break;
            }
            result.add(dateToString(c.getTime(),MM_DD));
            c.add(Calendar.DATE, 1);
        }
        return result;
    }

    /**
     * 获取所有时间区间天日期
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<String> getBetweentDateDD(Date startDate, Date endDate){
        List<String> result = new ArrayList<>();
        if (startDate.getTime() > endDate.getTime()){
            return result;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        while (true){
            if (dateToString(c.getTime(), YYYY_MM_DD).equals(dateToString(endDate, YYYY_MM_DD))){
                result.add(dateToString(c.getTime(),DD));
                break;
            }
            result.add(dateToString(c.getTime(),DD));
            c.add(Calendar.DATE, 1);
        }
        return result;
    }

    /**
     * 获取本周的第一天 (周一)
     * @return String
     * **/
    public static String getWeekStart(){
        Calendar cal=Calendar.getInstance();
        cal.add(Calendar.WEEK_OF_MONTH, 0);
        cal.set(Calendar.DAY_OF_WEEK, 2);
        Date time=cal.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time)+" 00:00:00";
    }

    /**
     * localDate转date
     * @param date
     * @return
     */
    public static Date localDateToDate(LocalDate date) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = date.atStartOfDay().atZone(zone).toInstant();
        return Date.from(instant);
    }

    /**
     * 获取所有时间区间天日期
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<String> getBetweentDateYYYYMMDD(Date startDate, Date endDate){
        List<String> result = new ArrayList<>();
        if (startDate.getTime() > endDate.getTime()){
            return result;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        while (true){
            if (dateToString(c.getTime(), YYYY_MM_DD).equals(dateToString(endDate, YYYY_MM_DD))){
                result.add(dateToString(c.getTime(),YYYY_MM_DD));
                break;
            }
            result.add(dateToString(c.getTime(),YYYY_MM_DD));
            c.add(Calendar.DATE, 1);
        }
        return result;
    }

    /**
     * 获取当前日期是星期几
     * @param date
     * @return 当前日期是星期几
     */
    public static String getWeekdayOfDate(Date date) {
        String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0){
            w = 0;
        }
        return weekDays[w];
    }


    /**
     * 获取当前日期
     */
    public static Date getCurrentDateYMD(){
        return getHmd(toYmd(new Date()));
    }

    public static void main(String[] args) {
//        System.out.println(getDayOfWeekDate(getHmd("2021-01-01"), Calendar.MONDAY));
//        System.out.println(getDayOfWeekDate(getHmd("2020-12-31"), Calendar.MONDAY));
//        System.out.println(getDayOfWeekDate(getHmd("2021-01-01"), Calendar.SUNDAY));
//        System.out.println(getDayOfWeekDate(getHmd("2020-12-31"), Calendar.SUNDAY));
//        System.out.println(getDayOfMonthDate(getHmd("2021-01-01"), 1));
//        System.out.println(getDayOfMonthDate(getHmd("2021-01-31"), 31));
//        System.out.println(getWeekOfYear(getHmd("2020-12-31")));
//        System.out.println(getWeekOfYear(getHmd("2021-01-01")));
//        System.out.println(getMonthofYear(getHmd("2021-01-01")));
//        System.out.println(getBetweentWeeks(getHmd("2021-08-15"), getHmd("2021-08-18")));
//        System.out.println(getBetweentMonths(getHmd("2021-08-01"), getHmd("2021-08-18")));
//        System.out.println(getMM("2021-12-01"));
//        System.out.println(getDD("2021-12-01"));
//        Date a = stringToDate("2021-08-29", YYYY_MM_DD);
//        Date b = stringToDate("2021-09-01", YYYY_MM_DD);
//        System.out.println(getBetweentDates(a, b));

//        System.out.println(DateUtile.getMonthEndDay("2021-09-01"));
        System.out.println(calculateWeeksBetween("2024-10-14"));
    }
}
